package com.study.hot.architecture.mvx.mvvm.model;

/**
 * <pre>
 *     author : slx
 *     time   : 2020/11/20
 *     desc   : 游戏
 * </pre>
 */
public class Board {
    // 提取属于model层的变量
    // 棋盘 3*3
    private Cell[][] cells = new Cell[3][3];
    // 胜利者
    private Player winner;
    // 当前轮到哪个文件
    private Player currentTurn;
    // 当前游戏状态
    private GameState state;

    public Board() {
        restart();
    }

    // 刷新游戏数据
    public void restart() {
        clearCells();
        // 默认x先下
        currentTurn = Player.X;
        // 游戏状态
        state = GameState.IN_PROGRESS;
        winner = null;
    }

    // 清除每个方格的棋子
    private void clearCells() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                cells[i][j] = new Cell();
            }
        }
    }

    // 获取当前胜利者
    public Player getWinner() {
        return winner;
    }

    /**
     * 标记当前玩家下棋位置,如果点击空白表示此次点击无效，如果游戏已经结束，本次点击忽略
     *
     * @param row 0..2
     * @param col 0..2
     * @return 返回当前选中，如果点击无效返回null
     */
    public Player mark(int row, int col) {
        Player playerThatMove = null;
        if (isValid(row, col)) {
            // 如果有效，记录玩家当前下棋的格子
            cells[row][col].setValue(currentTurn);
            playerThatMove = currentTurn;
            if (isWinnerMoveByPlayer(currentTurn, row, col)) {
                // 如果下完这步就胜利了
                state = GameState.FINISHED;
                winner = currentTurn;
            } else {
                // 轮到下一个玩家
                flipCurrentTurn();
            }
        }
        return playerThatMove;
    }

    // 切换游戏玩家
    private void flipCurrentTurn() {
        currentTurn = currentTurn == Player.X ? Player.O : Player.X;
    }

    // 判断当前玩家是否胜利
    private boolean isWinnerMoveByPlayer(Player player, int currentRow, int currentCol) {

        return (cells[currentRow][0].getValue() == player         // 3-行
                && cells[currentRow][1].getValue() == player
                && cells[currentRow][2].getValue() == player
                || cells[0][currentCol].getValue() == player      // 3-列
                && cells[1][currentCol].getValue() == player
                && cells[2][currentCol].getValue() == player
                || currentRow == currentCol            // 3-对角线
                && cells[0][0].getValue() == player
                && cells[1][1].getValue() == player
                && cells[2][2].getValue() == player
                || currentRow + currentCol == 2    // 3-反对角线
                && cells[0][2].getValue() == player
                && cells[1][1].getValue() == player
                && cells[2][0].getValue() == player);
    }

    // 此次点击是否有效，如果游戏已经结束、该方格已经有旗子表示无效
    private boolean isValid(int row, int col) {
        if (state == GameState.FINISHED) {
            return false;
        } else if (isCellAlreadySet(row, col)) {
            return false;
        } else {
            return true;
        }
    }

    // 判断当前方格是否已经有棋子
    private boolean isCellAlreadySet(int row, int col) {
        return cells[row][col].getValue() != null;
    }
}
